package rules

import (
	"fmt"
	"strings"

	"ddl_checker/internal/parser"
)

// FieldCommentRule 字段注释检查规则
type FieldCommentRule struct{}

// Name 规则名称
func (r *FieldCommentRule) Name() string {
	return "字段注释检查"
}

// Check 执行检查
func (r *FieldCommentRule) Check(data DDLCheckData) CheckResult {
	result := CheckResult{
		Status:  StatusPassed,
		Details: make([]string, 0),
	}

	if strings.TrimSpace(data.Script) == "" {
		result.Details = append(result.Details, "⚠️ 未提供DDL脚本，跳过字段注释检查")
		result.Status = StatusSkipped
		return result
	}

	// 解析DDL脚本
	hybridAnalyzer := parser.NewHybridAnalyzer()
	statements, err := hybridAnalyzer.ParseBatchDDL(data.Script, ";")
	if err != nil {
		result.Details = append(result.Details, "❌ 解析DDL脚本失败，无法检查字段注释")
		result.Status = StatusFailed
		return result
	}

	// 提取所有字段和注释信息
	allFields := make(map[string]bool)
	commentedFields := make(map[string]bool)

	for _, stmt := range statements {
		// 处理CREATE TABLE语句，提取字段
		if strings.Contains(strings.ToUpper(stmt.OriginalSQL), "CREATE TABLE") {
			fields := r.extractFieldsFromCreateTable(stmt.OriginalSQL)
			for field := range fields {
				allFields[field] = true
			}
		}
		// 处理ALTER TABLE语句，提取新添加的字段
		if strings.Contains(strings.ToUpper(stmt.OriginalSQL), "ALTER TABLE") {
			fields := r.extractFieldsFromAlterTable(stmt.OriginalSQL)
			for field := range fields {
				allFields[field] = true
			}
		}
		// 处理COMMENT ON COLUMN语句，记录有注释的字段
		if strings.Contains(strings.ToUpper(stmt.OriginalSQL), "COMMENT ON COLUMN") {
			field := r.extractFieldFromComment(stmt.OriginalSQL)
			if field != "" {
				commentedFields[field] = true
			}
		}
	}

	// 检查字段注释情况
	missingComments := 0
	for field := range allFields {
		if commentedFields[field] {
			result.Details = append(result.Details, fmt.Sprintf("✅ 字段 '%s' 有注释", field))
		} else {
			result.Details = append(result.Details, fmt.Sprintf("❌ 字段 '%s' 缺少注释", field))
			missingComments++
		}
	}

	if len(allFields) == 0 {
		result.Details = append(result.Details, "⚠️ 未找到字段定义")
	} else if missingComments == 0 {
		result.Details = append(result.Details, "✅ 该语句所有字段都有注释")
	} else {
		result.Details = append(result.Details, fmt.Sprintf("❌ 该语句有 %d 个字段缺少注释", missingComments))
		result.Status = StatusFailed
	}

	return result
}

// extractFieldsFromCreateTable 从CREATE TABLE语句中提取字段名
func (r *FieldCommentRule) extractFieldsFromCreateTable(sql string) map[string]bool {
	// 转换为大写以便处理
	upperSQL := strings.ToUpper(sql)

	// 提取CREATE TABLE后的字段定义部分
	fieldDefStart := strings.Index(upperSQL, "CREATE TABLE") + 12
	// 找到第一个左括号
	if start := strings.Index(upperSQL[fieldDefStart:], "("); start != -1 {
		fieldDefStart += start + 1
	} else {
		return make(map[string]bool)
	}

	// 提取字段定义部分（到右括号）
	fieldDefEnd := strings.Index(upperSQL[fieldDefStart:], ")")
	if fieldDefEnd == -1 {
		return make(map[string]bool)
	}
	fieldDefEnd += fieldDefStart

	fieldDefinitions := sql[fieldDefStart:fieldDefEnd]

	// 分割字段定义
	fieldDefs := strings.Split(fieldDefinitions, ",")
	fields := make(map[string]bool)

	for _, fieldDef := range fieldDefs {
		fieldDef = strings.TrimSpace(fieldDef)
		if fieldDef == "" {
			continue
		}

		// 提取字段名（第一个单词）
		parts := strings.Fields(fieldDef)
		if len(parts) == 0 {
			continue
		}

		fieldName := strings.Trim(parts[0], `"[]`)
		fields[fieldName] = true
	}

	return fields
}

// extractFieldsFromAlterTable 从ALTER TABLE语句中提取字段名
func (r *FieldCommentRule) extractFieldsFromAlterTable(sql string) map[string]bool {
	// 转换为大写以便处理
	upperSQL := strings.ToUpper(sql)

	// 检查是否是ALTER TABLE ADD COLUMN语句
	if !strings.Contains(upperSQL, "ALTER TABLE") || !strings.Contains(upperSQL, "ADD") {
		return make(map[string]bool)
	}

	// 找到ADD关键字的位置
	addIndex := strings.Index(upperSQL, "ADD")
	if addIndex == -1 {
		return make(map[string]bool)
	}

	// 提取ADD后面的部分
	fieldDef := sql[addIndex+3:]
	fieldDef = strings.TrimSpace(fieldDef)

	// 如果有COLUMN关键字，跳过它
	if strings.Contains(strings.ToUpper(fieldDef), "COLUMN") {
		columnIndex := strings.Index(strings.ToUpper(fieldDef), "COLUMN")
		fieldDef = fieldDef[columnIndex+6:]
		fieldDef = strings.TrimSpace(fieldDef)
	}

	// 提取字段名（第一个单词）
	parts := strings.Fields(fieldDef)
	if len(parts) == 0 {
		return make(map[string]bool)
	}

	fieldName := strings.Trim(parts[0], `"[]`)
	fields := make(map[string]bool)
	fields[fieldName] = true

	return fields
}

// extractFieldFromComment 从COMMENT ON COLUMN语句中提取字段名
func (r *FieldCommentRule) extractFieldFromComment(sql string) string {
	// 转换为大写以便处理
	upperSQL := strings.ToUpper(sql)

	// 检查是否是COMMENT ON COLUMN语句
	if !strings.Contains(upperSQL, "COMMENT ON COLUMN") {
		return ""
	}

	// 提取COMMENT ON COLUMN后的部分
	commentStart := strings.Index(upperSQL, "COMMENT ON COLUMN") + 17
	if commentStart == 16 {
		return ""
	}

	// 提取字段名部分（到IS关键字之前）
	isIndex := strings.Index(upperSQL[commentStart:], " IS")
	if isIndex == -1 {
		return ""
	}

	fieldPart := sql[commentStart : commentStart+isIndex]
	fieldPart = strings.TrimSpace(fieldPart)

	// 提取最后一个点后面的部分（字段名）
	lastDot := strings.LastIndex(fieldPart, ".")
	if lastDot != -1 {
		fieldPart = fieldPart[lastDot+1:]
	}

	return strings.Trim(fieldPart, `"[]`)
}

// allPassed 检查所有检查项是否都通过
func (r *FieldCommentRule) allPassed(details []string) bool {
	for _, detail := range details {
		if strings.Contains(detail, "❌") {
			return false
		}
	}
	return true
}
